package code.homework;

import java.util.Deque;
import java.util.LinkedList;

/**
 * @author cc
 * @create 2023-01-20  16:46
 */
public class MaxSlidingWindow {

    /**
     * 给你一个整数数组 nums，有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
     *
     * 返回 滑动窗口中的最大值 。
     *
     *  
     *
     * 示例 1：
     *
     * 输入：nums = [1,3,-1,-3,5,3,6,7], k = 3
     * 输出：[3,3,5,5,6,7]
     * 解释：
     * 滑动窗口的位置                最大值
     * ---------------               -----
     * [1  3  -1] -3  5  3  6  7       3
     *  1 [3  -1  -3] 5  3  6  7       3
     *  1  3 [-1  -3  5] 3  6  7       5
     *  1  3  -1 [-3  5  3] 6  7       5
     *  1  3  -1  -3 [5  3  6] 7       6
     *  1  3  -1  -3  5 [3  6  7]      7
     * 示例 2：
     *
     * 输入：nums = [1], k = 1
     * 输出：[1]
     *  
     *
     * 提示：
     *
     * 1 <= nums.length <= 105
     * -104 <= nums[i] <= 104
     * 1 <= k <= nums.length
     *
     * 来源：力扣（LeetCode）
     * 链接：https://leetcode.cn/problems/sliding-window-maximum
     * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
     */

    /**
     *
     *
     * 输入：nums = [1,3,-1,-3,5,3,6,7], k = 3
     * 输出：[3,3,5,5,6,7]
     * 解释：
     * 滑动窗口的位置                最大值
     * ---------------               -----
     * [1  3  -1] -3  5  3  6  7       3
     *  1 [3  -1  -3] 5  3  6  7       3
     *  1  3 [-1  -3  5] 3  6  7       5
     *  1  3  -1 [-3  5  3] 6  7       5
     *  1  3  -1  -3 [5  3  6] 7       6
     *  1  3  -1  -3  5 [3  6  7]      7
     *
     *  [-1,6,1]   -> 2.while 前一个元素 比后一个数据小，出队列
     *  [-3,-1,3]
     *  [5,-3,-1]  -> 1.入元素后，队列长度为3 时，出头部元素
     *
     *
     */
    public static int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Element> deque = new LinkedList();
        int[] result = new int[nums.length -k +1];
        int count = 1;

        for(int i = 0 ; i < nums.length ; i ++,count ++) {
            Element last = deque.peekLast();
            Element first = deque.peekFirst();
            if(count >= k  && !deque.isEmpty() && (i - deque.peekLast().getIndex()) >= k){
                deque.pollLast();
            }

            while (!deque.isEmpty() && deque.peekFirst().getValue() <= nums[i] ) {
                deque.pollFirst();
            }
            deque.push(new Element(i,nums[i]));
            if(count >= k) {
                result[count - k] = deque.peekLast().getValue();
            }
        }

        return result;
    }

     static class Element {
        int index;
        int value;
        public Element(int index ,int value){
            this.index = index;
            this.value = value;
        }

        public int getIndex() {
            return this.index;
        }

        public int getValue() {
            return this.value;
        }
    }

    public static void main(String[] args) {
        int[] nums = {7,2,4};
        maxSlidingWindow(nums,2);
    }
}
